﻿
//系统参数
namespace n_Node
{
using System;
using System.Drawing;
using n_SG;
using System.Windows.Forms;
using n_MusicFunction;

public class TNode
{
	public static bool DebugMode;
	
	public n_TNodeSet.TNodeSet owner;
	
	//节点坐标
	public int X;
	public int Y;
	//宽度和高度
	public int Width;
	public int Height;
	
	//音符, 数值为按照1=C方式存储, 1 = 60
	public int Tone;
	
	//时值
	//n分音符	时值
	//1			128
	//2			64
	//4			32
	//8			16
	//16		8
	//32		4
	//64		2
	//128		1
	public int Time;
	
	//所在的小节分数
	public int Cent;
	
	//简谱1代表的数值, 默认为60
	public static int DoEqual;
	
	//时值单位
	public static int TimeTick;
	
	//单位音符数目
	public static int PiN;
	//单位音符的时值
	public static int Fen;
	
	
	public bool LianYin;
	
	//时值错误
	public bool TimeError;
	
	const int FonfSize = 11;
	const int PerDLineHeigh = 3;
	
	public const int PerWidth = 13;
	public const int PerHeight = 50;
	const int PerLevelHeight = 5;
	
	public bool isFirstColumn;
	public bool isFirst;
	public bool isEnd;
	
	bool MouseOn;
	
	Color fc;
	
	//构造函数
	public TNode( n_TNodeSet.TNodeSet o, int to, int ti )
	{
		owner = o;
		
		Tone = to;
		Time = ti;
		MouseOn = false;
		
		TimeError = false;
		LianYin = false;
		
		fc = Color.Black;
	}
	
	//获取一个小节的时值
	public static int GetPercent()
	{
		int d = 0;
		if( Fen == 1 ) d = 128;
		if( Fen == 2 ) d = 64;
		if( Fen == 4 ) d = 32;
		if( Fen == 8 ) d = 16;
		if( Fen == 16 ) d = 8;
		if( Fen == 32 ) d = 4;
		if( Fen == 64 ) d = 2;
		if( Fen == 128 ) d = 1;
		
		if( d == 0 ) {
			n_Main.Program.MusicError( "不支持的音符分数:" + Fen );
		}
		return d * PiN;
	}
	
	//绘图函数
	public void Draw( bool s, bool isPlay )
	{
		if( TimeError ) {
			fc = Color.Red;
		}
		else {
			if( owner.Channel == 0 ) {
				fc = Color.Black;
			}
			else {
				fc = Color.MediumOrchid;
			}
		}
		int MidX = X + PerWidth/2 + 1;
		int MidY = Y + Height/2;
		int CurrentY = Y + Height - 15;
		
		int Percent = GetPercent();
		
		//绘制调试方框
		if( DebugMode ) {
			SG.MRectangle.Draw( Color.Silver, 1, X, Y, Width, Height );
		}
		//如果选中
		if( s ) {
			SG.MRectangle.Fill( Color.LightSteelBlue, X, Y, Width, Height );
			SG.MRectangle.Draw( Color.Blue, 1, X, Y, Width, Height );
		}
		else {
			if( MouseOn ) {
				SG.MRectangle.Fill( Color.Silver, X, Y, Width, Height );
				//SG.MRectangle.Draw( Color.Gray, 1, X, Y, Width, Height );
			}
			if( isPlay ) {
				SG.MRectangle.Fill( Color.LightBlue, X, Y, Width, Height );
				SG.MRectangle.Draw( Color.Blue, 1, X, Y, Width, Height );
			}
		}
		int Level = MusicFunction.GetLevel( Tone );
		int of = 0;
		int SimpleD = MusicFunction.GetSimpleNumer( Tone, ref of );
		
		//绘制简谱基本名称
		SG.MString.DrawAtCenter( SimpleD.ToString(), fc, FonfSize, MidX - 1, MidY );
		if( of != 0 ) {
			SG.MString.DrawAtCenter( "♭", fc, 8, MidX - 7, MidY - 5 );
		}
		
		//绘制时值
		int y = MidY - 2;
		int PointY = y + 2;
		int DotOffset = PerWidth;
		switch( Time ) {
			case 1:
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh * 2 );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh * 3 );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh * 4 );
				break;
			case 2:
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh * 2 );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh * 3 );
				break;
			case 3:
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX + PerWidth, CurrentY );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX + PerWidth, CurrentY + PerDLineHeigh );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX + PerWidth, CurrentY + PerDLineHeigh * 2 );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX + PerWidth, CurrentY + PerDLineHeigh * 3 );
				
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh * 2 );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh * 3 );
				SG.MString.DrawAtCenter( ".", fc, FonfSize, MidX + DotOffset, PointY );
				break;
			case 4:
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh * 2 );
				break;
			case 6:
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX + PerWidth, CurrentY );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX + PerWidth, CurrentY + PerDLineHeigh );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX + PerWidth, CurrentY + PerDLineHeigh * 2 );
				                        
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh * 2 );
				SG.MString.DrawAtCenter( ".", fc, FonfSize, MidX + DotOffset, PointY );
				break;
			case 8:
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh );
				break;
			case 12:
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX + PerWidth, CurrentY );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX + PerWidth, CurrentY + PerDLineHeigh );
				
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY );
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY + PerDLineHeigh );
				SG.MString.DrawAtCenter( ".", fc, FonfSize, MidX + DotOffset, PointY );
				break;
			case 16:
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY );
				break;
			case 24:
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX + PerWidth, CurrentY );
				
				SG.MString.DrawAtCenter( "―", fc, FonfSize, MidX, CurrentY );
				SG.MString.DrawAtCenter( ".", fc, FonfSize, MidX + DotOffset, PointY );
				break;
			case 32:
				break;
			case 48:
				SG.MString.DrawAtCenter( ".", fc, FonfSize, MidX + DotOffset, PointY );
				break;
			case 64:
				if( Cent + 32 >= Percent ) {
					DrawLine( MidX - 1 + PerWidth * 1, MidY );
					SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 2, MidY );
				}
				else {
					SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth, MidY );
				}
				break;
			case 96:
				if( Cent + 32 >= Percent ) {
					DrawLine( MidX - 1 + PerWidth * 1, MidY );
					SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 2, MidY );
					SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 3, MidY );
				}
				else {
					SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth, MidY );
					if( Cent + 64 >= Percent ) {
						DrawLine( MidX - 1 + PerWidth * 2, MidY );
						SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 3, MidY );
					}
					else {
						SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 2, MidY );
					}
				}
				break;
			case 128:
				if( Cent + 32 >= Percent ) {
					DrawLine( MidX - 1 + PerWidth * 1, MidY );
					SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 2, MidY );
					SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 3, MidY );
					SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 4, MidY );
				}
				else {
					SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth, MidY );
					if( Cent + 64 >= Percent ) {
						DrawLine( MidX - 1 + PerWidth * 2, MidY );
						SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 3, MidY );
						SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 4, MidY );
					}
					else {
						SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 2, MidY );
						if( Cent + 96 >= Percent ) {
							DrawLine( MidX - 1 + PerWidth * 3, MidY );
							SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 4, MidY );
						}
						else {
							SG.MString.DrawAtCenter( "-", fc, FonfSize, MidX - 1 + PerWidth * 3, MidY );
						}
					}
				}
				break;
			default:
				n_Main.Program.MusicError( "不支持的时值: " + Time );
				break;
		}
		//if( Cent + Time == Percent ) {
		if( isFirst ) {
			if( isFirstColumn ) {
				DrawLine( X - 8, MidY );
				DrawLine( X - 9, MidY );
			}
			//else {
				DrawLine( X - 6, MidY );
			//}
		}
		DrawLevel( Level );
	}
	
	//在指定位置显示音高符号,根据时值作适当调整
	void DrawLevel( int Level )
	{
		if( Level == 5 ) {
			return;
		}
		int CurrentX = X + PerWidth/2 + 2;
		
		if( Level > 5 ) {
			int LevelNumber = Level - 5;
			for( int i = 0; i < LevelNumber; ++i ) {
				SG.MString.DrawAtCenter( ".", fc, FonfSize, CurrentX, Y + 11 - i * PerLevelHeight );
			}
		}
		else {
			int YOffset;
			if( Time < 2 ) {
				YOffset = 5;
			}
			else if( Time < 4 ) {
				YOffset = 4;
			}
			else if( Time < 8 ) {
				YOffset = 3;
			}
			else if( Time < 16 ) {
				YOffset = 2;
			}
			else if( Time < 32 ) {
				YOffset = 1;
			}
			else {
				YOffset = 0;
			}
			int StartY = Y + 30 + YOffset * PerDLineHeigh;;
			int LevelNumber = 5 - Level;
			for( int i = 0; i < LevelNumber; ++i ) {
				SG.MString.DrawAtCenter( ".", fc, FonfSize, CurrentX, StartY + i * PerLevelHeight );
			}
		}
	}
	
	//在指定位置画一个分割线
	void DrawLine( int x, int y )
	{
		//SG.MLine.Draw( Color.Black, 1, x - 1, y - 13, x - 1, y + 13 );
		
		if( this.owner.Channel == 0 ) {
			SG.MLine.Draw( Color.Black, 1, x - 1, y - 15, x - 1, y + 25 );
		}
		else {
			SG.MLine.Draw( Color.Black, 1, x - 1, y - 25, x - 1, y + 15 );
		}
	}
	
	//鼠标按下事件
	public bool MouseDown( PointF p )
	{
		return MouseOn;
	}
	
	//鼠标松开事件
	public void MouseUp( PointF p )
	{
		
	}
	
	//鼠标移动事件
	public void MouseMove( PointF p )
	{
		if( p.X >= X && p.X < X + Width && p.Y >= Y && p.Y < Y + Height ) {
			MouseOn = true;
		}
		else {
			MouseOn = false;
		}
	}
}
}

